package joomz;

import jbxml.Component;
import jbxml.Reflector;

import java.util.List;
import javax.script.Bindings;


public abstract class Abstract
    extends java.lang.Object
    implements Component.Child,
               Component.AddText
{

    protected String id, label, description;

    protected Reflector reflector;

    protected Component parent;

    protected Event event;

    protected boolean special;


    protected List<Item> items;

    protected List<joomz.Object> objects;

    protected List<Direction> directions;

    protected List<Action> actions;

    protected List<Location> map;

    protected Player player;


    public Abstract(){
        super();
    }


    public final String getId(){
        return this.id;
    }
    public final void setId(String id){
        if (null != id){
            this.id = id;

            if (null == this.label)
                this.label = id;
        }
    }
    public final String getLabel(){
        return this.label;
    }
    public final void setLabel(String label){
        this.label = label;
    }
    public final String getDescription(){
        return this.description;
    }
    public final void setDescription(String description){
        this.description = description;
    }
    public final Event getEvent(){
        return this.event;
    }
    public final void setEvent(Event event){
        this.event = event;
    }
    public boolean isSpecial(){
        return this.special;
    }
    public void setSpecial(boolean value){
        this.special = value;
    }

    public abstract boolean isValid();

    public void init(Bindings local){
        if (null != this.items){
            for (Item item : this.items){
                item.init(local);
            }
        }
        if (null != this.directions){
            for (Direction direction : this.directions){
                direction.init(local);
            }
        }
        if (null != this.actions){
            for (Action action : this.actions){
                action.init(local);
            }
        }
        if (null != this.map){
            for (Location location : this.map){
                location.init(local);
            }
        }
        if (null != this.player)
            this.player.init(local);
    }

    public List<Item> getItems(){
        List<Item> items = this.items;
        if (null == items){
            items = new java.util.ArrayList<Item>();
            this.items = items;
        }
        return items;
    }
    public boolean setItems(List<Item> items){
        if (null != items){
            this.items = items;
            return true;
        }
        else
            return false;
    }
    public List<joomz.Object> getObjects(){
        List<joomz.Object> objects = this.objects;
        if (null == objects){
            objects = new java.util.ArrayList<joomz.Object>();
            this.objects = objects;
        }
        return objects;
    }
    public boolean setObjects(List<joomz.Object> objects){
        if (null != objects){
            this.objects = objects;
            return true;
        }
        else
            return false;
    }
    public List<Direction> getDirections(){
        List<Direction> directions = this.directions;
        if (null == directions){
            directions = new java.util.ArrayList<Direction>();
            this.directions = directions;
        }
        return directions;
    }
    public boolean setDirections(List<Direction> directions){
        if (null != directions){
            this.directions = directions;
            return true;
        }
        else
            return false;
    }
    public List<Action> getActions(){
        List<Action> actions = this.actions;
        if (null == actions){
            actions = new java.util.ArrayList<Action>();
            this.actions = actions;
        }
        return actions;
    }
    public boolean setActions(List<Action> actions){
        if (null != actions){
            this.actions = actions;
            return true;
        }
        else
            return false;
    }
    public Action getActionFor(Action pattern){
        for (Action action : this.actions){
            if (pattern == action || action.matches(pattern))
                return action;
        }
        return null;
    }
    public List<Action> listActionFor(Action pattern){
        List<Action> list = new java.util.ArrayList<Action>();
        for (Action action : this.actions){
            if (pattern == action || action.matches(pattern))
                list.add(action);
        }
        return list;
    }
    public Action getActionFor(String actor){
        for (Action action : this.actions){
            if (action.hasActor(actor))
                return action;
        }
        return null;
    }
    public List<Action> listActionFor(String actor){
        List<Action> list = new java.util.ArrayList<Action>();
        for (Action action : this.actions){
            if (action.hasActor(actor))
                list.add(action);
        }
        return list;
    }
    public List<Location> getMap(){
        List<Location> map = this.map;
        if (null == map){
            map = new java.util.ArrayList<Location>();
            this.map = map;
        }
        return map;
    }
    public boolean setMap(List<Location> map){
        if (null != map){
            this.map = map;
            return true;
        }
        else
            return false;
    }
    public Player getPlayer(){
        return this.player;
    }
    public boolean setPlayer(Player player){
        if (null != player){
            this.player = player;
            return true;
        }
        else
            return false;
    }
    public final Reflector getReflect(){
        return this.reflector;
    }
    public final Component getParent(){
        return this.parent;
    }
    public final void setParent(Component parent){
        this.parent = parent;
    }
    public final void startElement(Reflector reflector){
        this.reflector = reflector;
    }
    public final void endElement(){
    }
    public final void addElementText(javax.xml.stream.Location loc, String characters){
        if (null != characters){
            characters = characters.trim();
            if (null != this.description)
                this.description = NormWS(this.description+' '+characters);
            else
                this.description = NormWS(characters);
        }
    }
    public boolean equals(Object that){
        if (this == that)
            return true;
        else if (that instanceof Abstract){
            Abstract athat = (Abstract)that;
            if (null != this.id && null != athat.id)
                return (this.id.equals(athat.id));
        }
        return false;
    }

    protected final static String NormWS(String text){
        String[] tokens = text.split("[ \r\n\t]");
        if (0 == tokens.length)
            return text;
        else {
            StringBuilder content = new StringBuilder();
            for (String line: tokens){
                if (0 < content.length() && ' ' != content.charAt(content.length()-1))
                    content.append(' ');
                content.append(line);
            }
            return content.toString();
        }
    }
}
